package com.feidee.data.report.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.feidee.data.report.constant.Constant;
import com.feidee.data.report.dao.*;
import com.feidee.data.report.model.*;
import com.feidee.data.report.model.Dependency.DataResourcesStatusModel;
import com.feidee.data.report.model.Dependency.DependencyModel;
import com.feidee.data.report.model.Dependency.ReportDependencyStatusModel;
import com.feidee.data.report.service.DataReporterService;
import com.feidee.data.report.util.*;
import com.feidee.data.report.util.threadutil.ThreadPoolUtil;
import com.feidee.fdcommon.configuration.CustomConfiguration;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Future;
import java.util.concurrent.PriorityBlockingQueue;

@Service("reporterService")
public class DataReporterServiceImpl implements DataReporterService {

    @Resource(shareable = true)
    private IImpalaDao impalaDao;
    @Resource(shareable = true)
    private IHiveDao hiveDao;
    @Resource(shareable = true)
    private IMysqlDao mysqlDao;
    @Resource(shareable = true)
    private ISparkDao sparkDao;
    @Resource(shareable = true)
    private ISnappyDataDao snappyDataDao;
    @Resource(shareable = true)
    private IPublishReportDao crPublishDao;
    @Resource(shareable = true)
    private ICustomReportDao customReportDao;
    @Resource(shareable = true)
    private IReportMetadataOpr reportMetadataOpr;
    @Resource(shareable = true)
    private IReportStatusMachine reportStatusMachine;
    @Resource(shareable = true)
    private ICRCommonOprDao crCommonOprDao;
    @Resource(shareable = true)
    private IReportAndSourceStatusDao reportAndSourceStatusDao;

    private static Logger logger = Logger.getLogger(DataReporterServiceImpl.class);

    /**
     * 执行报表
     */
    @Override
    public int execute(ReportParam rp) {
        /* 如果直接提供hql和sql，则不需要从mysql数据库中获取hqlsql */
        PriorityBlockingQueue<ArrayList<ReportConfiguration>> hqlSqlQueue = new PriorityBlockingQueue<>(
                Constant.QUEUE_SIZE, new ReportMetadataComparator());
        //  存储依赖检查未通过的报表（或数据源检查没通过）等待被依赖的报表执行成功后再添加至队列中执行
        Map<String, ArrayList<ReportConfiguration>> dependencyMap = new ConcurrentHashMap<>();

        //	记录当前活跃机房IP
        Constant.CURRENT_ALIVE_HOST_IP = ToolUtils.getHostAddress();
        reportAndSourceStatusDao.recordHostIp();

        if (ToolUtils.isNotNull(rp.getHql()) && ToolUtils.isNotNull(rp.getMysql())) {
            logger.info("#### HQL And SQL Are Provided Manually... ####");
            ReportConfiguration reportconfiguration = new ReportConfiguration(rp.getKpi(), "Manual-Provide",
                    rp.getHql(), rp.getMysql(), "7", rp.getOpr(), rp.getEng(), rp.getProcess_class());
            reportconfiguration.setTable_type(rp.getTable_type());
            reportconfiguration.setMysql_table(rp.getMysql_table());
            reportconfiguration.setMysql_keys(rp.getMysql_keys());
            reportconfiguration.setIsCustom(rp.getIsCustom());
            reportconfiguration.setEnqueueTime(System.currentTimeMillis());
            reportconfiguration.setRunHistory(rp.getHistory());
            reportconfiguration.setRunPriority(1);
            reportconfiguration.setIsEnable(rp.getEnable());
            reportconfiguration.setIsScheduler("0");
            ArrayList<ReportConfiguration> list = new ArrayList<>();
            list.add(reportconfiguration);
            hqlSqlQueue.offer(list);
            // 手动指定的报表直接提交到线程池即可
            ThreadPoolUtil.submitReportExecTask(new QueryThread(hqlSqlQueue, dependencyMap, hiveDao, impalaDao,
                    mysqlDao,
                    sparkDao, snappyDataDao, Constant.TASK_RES_RETURN_URI, rp, reportAndSourceStatusDao, ""));
        } else if (null != rp.getDataMap() && 0 != rp.getDataMap().size()) {  //执行一组报表的sql
            logger.info("#### Collection of HQL AND SQL Are Provided Manually... ####");
            Map<String, ReportConfiguration> dataMap = rp.getDataMap();
            ArrayList<ReportConfiguration> list = new ArrayList<>();
            // 按index索引报表执行信息，装载到list中
            // 自定义报表拼接Mysql时有可能存在reportKey_1,reportKey_3,不存在reportKey_2的情况,
            // 需要按自然排序从Map中取出拼接到list中执行
            int mapSize = dataMap.size();
            int keyIndex = 1;
            int i = 1;
            while (i <= mapSize) {
                ReportConfiguration reportConfiguration = dataMap.get(String.valueOf(keyIndex));
                if (reportConfiguration != null) {
                    reportConfiguration.setIsEnable(rp.getEnable());
                    reportConfiguration.setIsScheduler("1");
                    reportConfiguration.setDataResources(rp.getDataResources());
                }
                while (null == reportConfiguration) {
                    keyIndex += 1;
                    reportConfiguration = dataMap.get(String.valueOf(keyIndex));
                }

                list.add(reportConfiguration);
                i += 1;
                keyIndex += 1;
            }
            hqlSqlQueue.offer(list);
            ThreadPoolUtil.submitReportExecTask(new QueryThread(hqlSqlQueue, dependencyMap, hiveDao, impalaDao,
                    mysqlDao,
                    sparkDao, snappyDataDao, Constant.TASK_RES_RETURN_URI, rp, reportAndSourceStatusDao, ""));
        } else {
            /* 从sql数据库中获取需要执行的hql */
            logger.info("#### Get SQL From Mysql DataBase... ####");
            int res = reportMetadataOpr.getHqlSql(rp, hqlSqlQueue);
            if (res != 0) {
                logger.info("#### Get Sql Context failed...... ####");
            }

            /* 将hql-sql提交给线程池执行, */
            int threadNum = Constant.THREAD_NUM;
            int hqlSqlQueueSize = hqlSqlQueue.size();
            if (hqlSqlQueueSize < Constant.THREAD_NUM) {
                threadNum = hqlSqlQueueSize;
            }
            logger.info("#### QUEUE SIZE : " + hqlSqlQueueSize + " ,并行度:" + threadNum
                    + " ,Start to submit, Query Thread start...... ####");
            if (hqlSqlQueueSize == 0) {
                logger.info("筛选运行的报表个数为0，运行结束！");
                return 0;
            }
            List<Callable<Integer>> threadList = new ArrayList<>();
            String groupName = ThreadPoolUtil.getUuid();
            for (int i = 0; i < threadNum; i++) {
                threadList.add(new QueryThread(hqlSqlQueue, dependencyMap, hiveDao, impalaDao, mysqlDao,
                        sparkDao, snappyDataDao, Constant.TASK_RES_RETURN_URI, rp, reportAndSourceStatusDao,
                        groupName));
            }
            //提交报表执行线程
            ThreadPoolUtil.submitReportExecTask(groupName, threadList);
            //提交报表监控线程
            ThreadPoolUtil.submitReportMonitorTask(new MonitorThread(groupName, hqlSqlQueue, threadNum));
        }

        return 0;
    }

    /**
     * 校验该报表依赖的数据源是否到位
     *
     * @param data
     * @return
     */
    @Override
    public boolean verifyDataResourcesDependency(CustomReportModel data) {
        // 若校验不通过返回前端结果
        String responseStr = null;
        boolean isReady = true;
        String status;
        String validSourceTblData = reportAndSourceStatusDao.validSourceTblData("0", data.getApplysqlname(),
                data.getDataResources(), "1", Long.MAX_VALUE, false);
        String[] validSourceTblDataArray = validSourceTblData.split("€", -1);
        status = validSourceTblDataArray[0];
        if ("-2".equals(status)) {
            responseStr = "依赖源表" + validSourceTblDataArray[1] + "未同步,放弃执行";
            isReady = false;
        } else if ("-3".equals(status)) {
            responseStr = "依赖源表" + validSourceTblDataArray[1] + "同步失败,放弃执行";
            isReady = false;
        } else if ("-4".equals(status)) {
            responseStr = "依赖源表" + validSourceTblDataArray[1] + "校验不通过,放弃执行";
            isReady = false;
        }
        if (!isReady) {
            ResultResponseUtil.sleepThenResultResponse(Constant.TASK_RES_RETURN_URI, data.getId(), "3", responseStr);
        }
        return isReady;
    }

    /**
     * 自定义报表操作
     *
     * @param crm
     */
    public Future<?> customReportOpr(final CustomReportModel crm) {
        // 异步执行
        return ThreadPoolUtil.submitReportExecTask(() -> {
            try {
                // 前端提交报表统一设置为0
                crm.setEnable("0");
                // 前端提交废除执行周期，统一设置为每天十点执行
                crm.setPeriod("D10");
                // 根据前端传过来的中文优先级转换成具体的数字
                crm.setPriority(Constant.CUSTOM_PRIORITY.get(crm.getPriority()));
                logger.info("自定义报表参数: " + crm);
            } catch (Exception e) {
                logger.info("自定义报表参数错误: ", e);
                ResultResponseUtil.resultResponse(Constant.TASK_RES_RETURN_URI, "00000", "3", "自定义报表参数错误");
                return;
            }

            //参数检查
            int checkRes = checkCustomReportParam(crm);
            if (0 != checkRes)
                return;

            //获取状态机状态
            String statusStr = reportStatusMachine.getStatus(crm);
            logger.info("自定义报表 " + crm.getId() + " => " + crm.getApplysqlname() + " 获取初始化状态结果:" + statusStr);
            String[] statusArray = statusStr.split(Constant.ERR_MSG_SPLIT_FLAG, -1); //将发布状态和状态机状态切分开
            String[] machineStatusArray = statusArray[1].split(Constant.CUSTOM_REPORT_STATUS_SPLIT, -1); //切分状态机状态
            List<String> statusList = Arrays.asList(machineStatusArray);

            if (Constant.CR_STATUS_NO_CHANGE.equals(statusArray[1])) { //无任何改动
                crNoChangeHandlerFunc(crm, statusArray[0]);
                return;
            }
            if (Constant.CR_STATUS_NEW_REPORT.equals(statusArray[1]) ||
                    Constant.CR_STATUS_CHANGE_NEED_ALL_EXECUTE.equals(statusArray[1])) {  //新增报表、非新增报表，改动需要执行所有流程
                crAllExecuteHandlerFunc(crm, statusArray[0]);
                return;
            }

            //剩余"3","4","5","6","7","8","9","10"号状态
            crStatusHandlerFunc(crm, statusArray[0], statusList);
        });

    }

    /**
     * 自定义报表提交参数检查
     *
     * @param crm
     * @return
     */
    public int checkCustomReportParam(CustomReportModel crm) {
        // 自定义报表参数检查,如果mysql列或hivesql为空,则视为非法自定义报表参数
        if ((null == crm.getMysqlColumn()) || crm.getMysqlColumn().isEmpty()) {
            logger.info("自定义报表:Mysql表列信息参数错误...");
            ResultResponseUtil.resultResponse(Constant.TASK_RES_RETURN_URI, crm.getId(), "3", "Mysql表列信息参数错误");
            return -1;
        }

        if ((null == crm.getHivesql()) || crm.getHivesql().isEmpty()) {
            logger.info("自定义报表:HiveSql信息错误...");
            ResultResponseUtil.resultResponse(Constant.TASK_RES_RETURN_URI, crm.getId(), "3", "HiveSql信息错误");
            return -1;
        }

        return 0;
    }

    /**
     * 自定义报表没有改动操作函数
     *
     * @param crm
     * @param pubStatus
     */
    public void crNoChangeHandlerFunc(CustomReportModel crm, String pubStatus) {
        if (Constant.CR_PUBSTATUS_ALREADY_PUBLISH.equals(pubStatus)) { //无改动并且已经发布过的报表，创建到正式表的视图供前端预览
            int res = customReportDao.createViewRefFormal(crm);
            if (0 == res) {
                logger.info("自定义报表 " + crm.getId() + " => " + crm.getApplysqlname() + " 无改动，执行成功!");
                ResultResponseUtil.resultResponse(Constant.TASK_RES_RETURN_URI, crm.getId(), "7",
                        "自定义报表执行成功,无改动需创建tmp表视图成功!");
            }
        } else {
            logger.info("自定义报表 " + crm.getId() + " => " + crm.getApplysqlname() + " 无改动，不需执行...");
            ResultResponseUtil.resultResponse(Constant.TASK_RES_RETURN_URI, crm.getId(), "7",
                    "自定义报表执行成功,无改动不需执行!");
        }
    }


    /**
     * 针对自定义报表新增报表["1"号状态]、改动需要全部重新执行的状态["2"号状态]
     *
     * @param crm
     * @param pubStatus
     */
    public void crAllExecuteHandlerFunc(CustomReportModel crm, String pubStatus) {
        // 自定义报表操作
        // 1.拼接并创建Mysql表
        int res = customReportDao.createReportMysqlTbl(crm);
        if (res != 0)
            return;
        //如果未发布，直接写入配置库并重新执行; 如果已发布，则拼接出Mysql后放入Map缓存,不写配置库,直接执行
        if (Constant.CR_PUBSTATUS_ALREADY_PUBLISH.equals(pubStatus)) {
            execReportManualMapSql(crm, pubStatus);
        } else {
            // 拼接HiveSql对应的Mysql语句并写入报表配置库report_sql表中
            res = crCommonOprDao.writeMysqlStrToDB(crm, pubStatus);
            if (res != 0)
                return;
            // 执行自定义报表(调用service层报表execute执行接口)
            execReportHiveSql(crm);
        }
        //此处现将元数据信息写入配置库中，如果执行失败就需要改sql再次提交
        //[如果执行失败了,编辑没有改动，再次提交,不会执行]
        reportStatusMachine.writeMetadataToMysql(crm);
    }

    /**
     * 自定义报表提交结果处理"3","4","5","6","7","8","9","10"号状态
     *
     * @param crm
     * @param pubStatus
     * @param statusList
     */
    private void crStatusHandlerFunc(CustomReportModel crm, String pubStatus, List<String> statusList) {
        String resMsg = "";
        boolean writeFlag = true;

        //处理"3","4","5","8","9","10"号状态
        String resStr = crCommonStatusHandlerFunc(crm, pubStatus, statusList);
        String[] resStrArr = resStr.split(Constant.CUSTOM_REPORT_STATUS_SPLIT, -1);
        writeFlag = Boolean.valueOf(resStrArr[1]);
        resMsg = resStrArr[0];

        //判断上面三个执行情况
        if (!writeFlag) {
            resMsg = ToolUtils.trimComma(resMsg);
            logger.info("自定义报表 " + crm.getId() + " => " + crm.getApplysqlname() + " 执行异常," + resMsg);
            ResultResponseUtil.resultResponse(Constant.TASK_RES_RETURN_URI, crm.getId(), "3",
                    "自定义报表修改发生异常," + resMsg);
            return;
        }

        if (statusList.contains(Constant.CR_STATUS_HIVESQL_CHANGE_HISTORYSQL_NOCHANGE)) {
            int res = customReportDao.createReportMysqlTbl(crm);
            if (res != 0) {
                writeFlag = false;
                resMsg += "创建tmp表失败,";
            } else {
                resMsg += "创建tmp表成功,";
            }
            //如果未发布，直接写入配置库并执行; 如果已发布，则拼接出Mysql后放入Map缓存,不写配置库,直接执行
            if (Constant.CR_PUBSTATUS_ALREADY_PUBLISH.equals(pubStatus)) {
                execReportManualMapSql(crm, pubStatus);
            } else {
                res = crCommonOprDao.writeMysqlStrToDB(crm, pubStatus);
                if (res != 0) {
                    writeFlag = false;
                    resMsg += "修改实时SQL配置入库失败!";
                } else {
                    resMsg += "修改实时SQL配置入库成功!";
                }
                execReportHiveSql(crm);
            }
        } else if (statusList.contains(Constant.CR_STATUS_HISTORYSQL_CHANGE_HIVESQL_NOCHANGE)) {
            if (Constant.CR_PUBSTATUS_NO_PUBLISH.equals(pubStatus)) { //未发布则修改配置库
                int res = crCommonOprDao.modifyHistorySqlNote(crm, pubStatus);
                if (0 == res) {
                    resMsg += "未发布修改历史SQL成功,";
                } else {
                    writeFlag = false;
                    resMsg += "未发布修改历史SQL异常!";
                }
            } else {  //已发布则不做任何操作，待发布后更新到配置库
                resMsg += "已发布不用修改历史SQL,";
            }
        }

        if (!statusList.contains(Constant.CR_STATUS_HIVESQL_CHANGE_HISTORYSQL_NOCHANGE)) { //如果不包含6,都要创建视图
            if (Constant.CR_PUBSTATUS_ALREADY_PUBLISH.equals(pubStatus) && writeFlag) {
                int viewRes = customReportDao.createViewRefFormal(crm);
                if (0 == viewRes) {
                    resMsg += "并且创建正式表视图成功!";
                } else {
                    writeFlag = false;
                    resMsg += "但创建正式表视图失败!";
                }
            }
        }
        //返回结果,上面三个状态，有一个失败，都不再写元数据表信息,防止提交重复的不再执行
        resMsg = ToolUtils.trimComma(resMsg);
        if (writeFlag) {
            logger.info("自定义报表 " + crm.getId() + " => " + crm.getApplysqlname() + " 执行成功," + resMsg);
            if (!statusList.contains(Constant.CR_STATUS_HIVESQL_CHANGE_HISTORYSQL_NOCHANGE)) {
                ResultResponseUtil.resultResponse(Constant.TASK_RES_RETURN_URI, crm.getId(), "2",
                        "自定义报表执行成功," + resMsg);
            }
            reportStatusMachine.writeMetadataToMysql(crm);
            return;
        } else {
            logger.info("自定义报表 " + crm.getId() + " => " + crm.getApplysqlname() + " 执行异常," + resMsg);
            ResultResponseUtil.resultResponse(Constant.TASK_RES_RETURN_URI, crm.getId(), "3",
                    "自定义报表修改发生异常," + resMsg);
            return;
        }
    }

    /**
     * 处理"3","4","5","8","9","10"状态
     *
     * @param crm
     * @param pubStatus
     * @param statusList
     * @return
     */
    private String crCommonStatusHandlerFunc(CustomReportModel crm, String pubStatus, List<String> statusList) {

        String resMsg = "";
        boolean writeFlag = true;
        if (statusList.contains(Constant.CR_STATUS_MYSQL_COLUMN_COMMENT_CHANGE)) {
            if (Constant.CR_PUBSTATUS_NO_PUBLISH.equals(pubStatus)) { //未发布则修改临时表
                int res = crCommonOprDao.modifyMysqlColNote(crm, pubStatus);
                if (0 == res) {
                    resMsg += "未发布修改Mysql注释成功,";
                } else {
                    writeFlag = false;
                    resMsg += "未发布修改Mysql注释异常,";
                }
            } else {  //已发布则不做任何操作，待发布后更新到正式表
                resMsg += "已发布不用修改Mysql注释,";
            }
        }
        if (statusList.contains(Constant.CR_STATUS_REPORT_PEROID_CHANGE)) {
            if (Constant.CR_PUBSTATUS_NO_PUBLISH.equals(pubStatus)) { //未发布则修改配置库
                int res = crCommonOprDao.modifyReportPeriod(crm, pubStatus);
                if (0 == res) {
                    resMsg += "未发布修改报表执行周期成功,";
                } else {
                    writeFlag = false;
                    resMsg += "未发布修改报表执行周期异常,";
                }
            } else {  //已发布则不做任何操作，待发布后更新到配置库
                resMsg += "已发布不用修改报表执行周期,";
            }
        }
        if (statusList.contains(Constant.CR_STATUS_REPORT_COMMENT_CHANGE)) {
            if (Constant.CR_PUBSTATUS_NO_PUBLISH.equals(pubStatus)) { //未发布则修改临时表
                int res = crCommonOprDao.modifyMysqlTblNote(crm, pubStatus);
                if (0 == res) {
                    resMsg += "未发布修改报表注释成功,";
                } else {
                    writeFlag = false;
                    resMsg += "未发布修改报表注释异常,";
                }
            } else {  //已发布则不做任何操作，待发布后更新正式表
                resMsg += "已发布不用修报表注释,";
            }
        }
        if (statusList.contains(Constant.CR_STATUS_REPORT_DEPENDENCY_CHANGE)) {
            if (Constant.CR_PUBSTATUS_NO_PUBLISH.equals(pubStatus)) { //未发布则修改配置库
                int res = crCommonOprDao.modifyReportDependency(crm, pubStatus);
                if (0 == res) {
                    resMsg += "未发布修改报表依赖信息成功,";
                } else {
                    writeFlag = false;
                    resMsg += "未发布修改报表依赖信息异常,";
                }
            } else {  //已发布则不做任何操作，待发布后更新正式表
                resMsg += "已发布不用修报表依赖信息,";
            }
        }
        if (statusList.contains(Constant.CR_STATUS_REPORT_PRIORITY_CHANGE)) {
            if (Constant.CR_PUBSTATUS_NO_PUBLISH.equals(pubStatus)) { //未发布则修改配置库
                int res = crCommonOprDao.modifyReportPriority(crm, pubStatus);
                if (0 == res) {
                    resMsg += "未发布修改报表优先级成功,";
                } else {
                    writeFlag = false;
                    resMsg += "未发布修改报表优先级异常,";
                }
            } else {  //已发布则不做任何操作，待发布后更新到配置库
                resMsg += "已发布不用修改报表优先级,";
            }
        }
        if (statusList.contains(Constant.CR_STATUS_DATA_RESOURCES_CHANGE)) {
            if (Constant.CR_PUBSTATUS_NO_PUBLISH.equals(pubStatus)) { //未发布则修改配置库
                int res = crCommonOprDao.modifyDataResources(crm, pubStatus);
                if (0 == res) {
                    resMsg += "未发布修改数据源成功,";
                } else {
                    writeFlag = false;
                    resMsg += "未发布修改数据源异常,";
                }
            } else {  //已发布则不做任何操作，待发布后更新到配置库
                resMsg += "已发布不用修改数据源,";
            }
        }

        return resMsg + Constant.CUSTOM_REPORT_STATUS_SPLIT + writeFlag;
    }

    /**
     * 发布自定义报表
     *
     * @param crpm
     * @return 0 成功 其他值 失败
     */
    public String crmPublishOpr(CustomReportModel crpm) {
        // 参数检查
        if (crpm == null || !ToolUtils.isNotNull(crpm.getApplysqlname())) {
            logger.info("发布自定义报表: 发布报表名参数错误......");
            return "-1" + Constant.ERR_MSG_SPLIT_FLAG + "发布自定义报表参数错误";
        }

        // 获取状态
        String statusStr = reportStatusMachine.getMachinePublishStatus(crpm);
        logger.info("发布自定义报表 " + crpm.getId() + " => " + crpm.getApplysqlname() + " 获取初始化状态结果:" + statusStr);
        String[] statusArray = statusStr.split(Constant.ERR_MSG_SPLIT_FLAG);//将发布状态和状态机状态切分开
        String[] machineStatusArray = statusArray[1].split(Constant.CUSTOM_REPORT_STATUS_SPLIT, -1); //切分状态机状态
        List<String> statusList = Arrays.asList(machineStatusArray);

        if (Constant.CR_STATUS_NO_CHANGE.equals(statusArray[1])) { //无任何改动
            return crPubNoChangeHandlerFunc(crpm, statusArray[0]);
        } else if (Constant.CR_PUBSTATUS_NO_PUBLISH.equals(statusArray[0])) {  //未发布
            return crPubAllExecuteHandlerFunc(crpm, statusArray[0]);
        } else {    //"1","2","3","4","5","6","7","8","9","10"号状态处理[由于多次修改提交,这几种状态可能混合在一起]
            return crPubStatusHandlerFunc(crpm, statusArray[0], statusList);
        }

    }

    /**
     * 发布自定义报表没有改动操作函数
     *
     * @param crpm
     * @param pubStatus
     * @return
     */
    private String crPubNoChangeHandlerFunc(CustomReportModel crpm, String pubStatus) {
        if ("1".equals(pubStatus)) { //无改动并且已经发布过的报表，删除到正式表的视图
            String res = crPublishDao.dropViewRefFormal(crpm);
            if (res.startsWith("0")) {
                logger.info("发布自定义报表 " + crpm.getId() + " => " + crpm.getApplysqlname()
                        + " 无改动，删除tmp表视图成功!");
                return "7" + Constant.ERR_MSG_SPLIT_FLAG + "发布自定义报表未改动,删除tmp表视图成功!";
            } else {
                logger.info("发布自定义报表 " + crpm.getId() + " => " + crpm.getApplysqlname()
                        + " 无改动，删除tmp表视图失败!");
                return "3" + Constant.ERR_MSG_SPLIT_FLAG + "发布自定义报表未改动,删除tmp表视图失败!";
            }
        } else {
            logger.info("发布自定义报表 " + crpm.getId() + " => " + crpm.getApplysqlname() + " 无改动，不需执行...");
            return "7" + Constant.ERR_MSG_SPLIT_FLAG + "发布自定义报表未改动,无需发布";
        }
    }

    /**
     * 针对自定义报表之前未发布状态情况处理
     *
     * @param crpm
     * @param pubStatus
     * @return
     */
    private String crPubAllExecuteHandlerFunc(CustomReportModel crpm, String pubStatus) {
        // 执行发布自定义操作
        String resStr = crPublishDao.crPublishReport(crpm);
        String[] resStrArray = resStr.split(Constant.ERR_MSG_SPLIT_FLAG, -1);
        // 执行自定义报表历史SQL
        if (resStr.startsWith("0")) {
            execReportHistorySql(crpm);
            reportStatusMachine.modifyCheckStatus(crpm);
            //自定义报表先返回状态8表示部分操作执行完成,待历史SQL执行完成后返回发布结果
            resStrArray[0] = "8";
            logger.info("发布自定义报表 " + crpm.getId() + " => " + crpm.getApplysqlname()
                    + " 发布报表成功,但是需要等待历史SQL执行完成后返回发布结果!");
        } else {
            logger.info("发布自定义报表 " + crpm.getId() + " => " + crpm.getApplysqlname() + " 发布报表异常!");
        }

        return resStrArray[0] + Constant.ERR_MSG_SPLIT_FLAG + resStrArray[1] + "[该报表之前未发布]";
    }

    /**
     * 自定义报表发布接口处理"1","2","3","4","5","6","7","8","9","10"号状态
     *
     * @param crpm
     * @param pubStatus
     * @param statusList
     * @return
     */
    private String crPubStatusHandlerFunc(CustomReportModel crpm, String pubStatus, List<String> statusList) {
        String resMsg = "";
        String code = "0";
        boolean alreadyDropView = false;  //控制返回日志结构
        //状态1新增报表、状态2非新增需要执行全部流程
        if (statusList.contains(Constant.CR_STATUS_NEW_REPORT) ||
                statusList.contains(Constant.CR_STATUS_CHANGE_NEED_ALL_EXECUTE)) {
            String[] resStr = crPubOneTwoStatusHandlerFunc(crpm, pubStatus, statusList)
                    .split(Constant.CUSTOM_REPORT_STATUS_SPLIT, -1);
            resMsg += resStr[1];
            if (!"0".equals(resStr[0])) {
                code = resStr[0];
            }
        }
        //状态3、4、5、8、9、10的处理
        String[] commonHandlerRes = crPubCommonStatusHandlerFunc(crpm, pubStatus, statusList)
                .split(Constant.CUSTOM_REPORT_STATUS_SPLIT, -1);
        alreadyDropView = Boolean.valueOf(commonHandlerRes[0]);
        resMsg += commonHandlerRes[2];
        if (!"0".equals(commonHandlerRes[1])) {
            code = commonHandlerRes[1];
        }
        //状态6处理
        if (statusList.contains(Constant.CR_STATUS_HIVESQL_CHANGE_HISTORYSQL_NOCHANGE) &&
                Constant.CR_PUBSTATUS_ALREADY_PUBLISH.equals(pubStatus)) {  //实时SQL改变并且已发布
            String[] resStr = crPubSixStatusHandlerFunc(crpm, pubStatus, statusList)
                    .split(Constant.CUSTOM_REPORT_STATUS_SPLIT, -1);
            resMsg += resStr[1];
            if (!"0".equals(resStr[0])) {
                code = resStr[0];
            }
        } else if (statusList.contains(Constant.CR_STATUS_HISTORYSQL_CHANGE_HIVESQL_NOCHANGE) &&
                Constant.CR_PUBSTATUS_ALREADY_PUBLISH.equals(pubStatus)) {  //状态7历史SQL改变并且已发布
            String[] resStr = crPubSevenStatusHandlerFunc(crpm, pubStatus, statusList, alreadyDropView)
                    .split(Constant.CUSTOM_REPORT_STATUS_SPLIT, -1);
            resMsg += resStr[1];
            if (!"0".equals(resStr[0])) {
                code = resStr[0];
            }
            //自定义报表如果执行了历史SQL,先返回状态8表示部分操作执行完成,待历史SQL执行完成后返回发布结果
            if ("0".equals(resStr[0]) && "0".equals(code)) {
                code = "8";
                logger.info("发布自定义报表 " + crpm.getId() + " => " + crpm.getApplysqlname()
                        + " 部分操作完成[状态7需执行历史SQL]，需等待历史SQL执行完成后返回发布结果!");
            }
        } else if ("0".equals(code) && (statusList.contains(Constant.CR_STATUS_NEW_REPORT) ||
                statusList.contains(Constant.CR_STATUS_CHANGE_NEED_ALL_EXECUTE))) {  //状态1,2需要执行历史SQL
            execReportHistorySql(crpm);
            //自定义报表如果执行了历史SQL,先返回状态8表示部分操作执行完成,待历史SQL执行完成后返回发布结果
            if ("0".equals(code)) {
                code = "8";
                logger.info("发布自定义报表 " + crpm.getId() + " => " + crpm.getApplysqlname()
                        + " 部分操作完成[状态1或2需执行ALL]，需等待历史SQL执行完成后返回发布结果!");
            }
        }
        //如果是执行成功[状态'0']或是部分执行成功但是等到历史SQL执行完成才能返回结果的[状态8]，需要清除综合状态码
        if ("0".equals(code) || "8".equals(code)) {
            reportStatusMachine.modifyCheckStatus(crpm);
        }

        return code + Constant.ERR_MSG_SPLIT_FLAG + ToolUtils.trimComma(resMsg);
    }

    /**
     * 发布自定义报表"1","2"号状态的处理
     *
     * @param crpm
     * @param pubStatus
     * @param statusList
     * @return
     */
    private String crPubOneTwoStatusHandlerFunc(CustomReportModel crpm, String pubStatus, List<String> statusList) {
        String resMsg = "";
        String code = "0";

        // 拼接HiveSql对应的Mysql语句并写入报表配置库report_sql表中[比如同时改了实时sql和历史sql]
        if (Constant.CR_PUBSTATUS_ALREADY_PUBLISH.equals(pubStatus)) {
            int res = crCommonOprDao.writeMysqlStrToDB(crpm, pubStatus);
            if (-1 == res) {
                code = "3";
                resMsg += "发布自定义报表配置修改写入配置库失败,";
            } else {
                resMsg += "发布自定义报表配置修改写入配置库成功,";
            }
        }
        // 执行发布自定义操作
        String resStr = crPublishDao.crPublishReport(crpm);
        if (resStr.startsWith("0")) {
            resMsg += "发布自定义报表rename表修改配置库成功,";
        } else {
            code = "3";
            resMsg += "发布自定义报表rename表修改配置库失败,";
        }

        return code + Constant.CUSTOM_REPORT_STATUS_SPLIT + resMsg;
    }

    /**
     * 发布自定义报表"3","4","5","8","9","10"号状态的处理
     *
     * @param crpm
     * @param pubStatus
     * @param statusList
     * @return
     */
    private String crPubCommonStatusHandlerFunc(CustomReportModel crpm, String pubStatus, List<String> statusList) {
        String resMsg = "";
        String code = "0";
        boolean alreadyDropView = false;  //控制返回日志结构

        if ((statusList.contains(Constant.CR_STATUS_MYSQL_COLUMN_COMMENT_CHANGE) &&
                Constant.CR_PUBSTATUS_ALREADY_PUBLISH.equals(pubStatus))   //Mysql注释改变并且已发布
                || (statusList.contains(Constant.CR_STATUS_REPORT_PEROID_CHANGE) &&
                Constant.CR_PUBSTATUS_ALREADY_PUBLISH.equals(pubStatus))   //报表执行周期改变并且已发布
                || (statusList.contains(Constant.CR_STATUS_REPORT_COMMENT_CHANGE) &&
                Constant.CR_PUBSTATUS_ALREADY_PUBLISH.equals(pubStatus))   //报表注释改变并且已发布
                || (statusList.contains(Constant.CR_STATUS_REPORT_DEPENDENCY_CHANGE) &&
                Constant.CR_PUBSTATUS_ALREADY_PUBLISH.equals(pubStatus))   //报表依赖改变并且已发布
                || (statusList.contains(Constant.CR_STATUS_REPORT_PRIORITY_CHANGE) &&
                Constant.CR_PUBSTATUS_ALREADY_PUBLISH.equals(pubStatus))   //报表优先级改变并且已发布
                || (statusList.contains(Constant.CR_STATUS_DATA_RESOURCES_CHANGE) &&
                Constant.CR_PUBSTATUS_ALREADY_PUBLISH.equals(pubStatus))   //报表数据源改变并且已发布
        ) {
            String resStr = crPublishDao.dropViewRefFormal(crpm);
            String[] resArray = resStr.split(Constant.ERR_MSG_SPLIT_FLAG, -1);
            alreadyDropView = true;
            resMsg += resArray[1] + ",";
            if (!"0".equals(resArray[0])) {
                code = resArray[0];
            }
            if (statusList.contains(Constant.CR_STATUS_MYSQL_COLUMN_COMMENT_CHANGE)) {
                int res = crCommonOprDao.modifyMysqlColNote(crpm, pubStatus);
                if (0 == res) {
                    resMsg += "发布自定义报表修改Mysql列注释成功,";
                } else {
                    code = "3";
                    resMsg += "发布自定义报表修改Mysql列注释失败,";
                }
            }
            if (statusList.contains(Constant.CR_STATUS_REPORT_PEROID_CHANGE)) {
                int res = crCommonOprDao.modifyReportPeriod(crpm, pubStatus);
                if (0 == res) {
                    resMsg += "发布自定义报表修改报表执行周期成功,";
                } else {
                    code = "3";
                    resMsg += "发布自定义报表修改报表执行周期失败,";
                }
            }
            if (statusList.contains(Constant.CR_STATUS_REPORT_COMMENT_CHANGE)) {
                int res = crCommonOprDao.modifyMysqlTblNote(crpm, pubStatus);
                if (0 == res) {
                    resMsg += "发布自定义报表修改报表注释成功,";
                } else {
                    code = "3";
                    resMsg += "发布自定义报表修改报表注释失败,";
                }
            }
            if (statusList.contains(Constant.CR_STATUS_REPORT_DEPENDENCY_CHANGE)) {
                int res = crCommonOprDao.modifyReportDependency(crpm, pubStatus);
                if (0 == res) {
                    resMsg += "发布自定义报表修改报表依赖信息成功,";
                } else {
                    code = "3";
                    resMsg += "发布自定义报表修改报表依赖信息失败,";
                }
            }
            if (statusList.contains(Constant.CR_STATUS_REPORT_PRIORITY_CHANGE)) {
                int res = crCommonOprDao.modifyReportPriority(crpm, pubStatus);
                if (0 == res) {
                    resMsg += "发布自定义报表修改报表优先级成功,";
                } else {
                    code = "3";
                    resMsg += "发布自定义报表修改报表优先级失败,";
                }
            }
            if (statusList.contains(Constant.CR_STATUS_DATA_RESOURCES_CHANGE)) {
                int res = crCommonOprDao.modifyDataResources(crpm, pubStatus);
                if (0 == res) {
                    resMsg += "发布自定义报表修改报表数据源成功,";
                } else {
                    code = "3";
                    resMsg += "发布自定义报表修改报表数据源失败,";
                }
            }
        }

        return String.valueOf(alreadyDropView) + Constant.CUSTOM_REPORT_STATUS_SPLIT +
                code + Constant.CUSTOM_REPORT_STATUS_SPLIT + resMsg;
    }

    /**
     * 修改报表执行周期
     * @param ustomReportModel
     * @return
     */
    public Boolean updatePeriod(CustomReportModel ustomReportModel){
        // 由于原来每天执行的run_date值为D10，因此此处需要做一下转换
        String period = ustomReportModel.getPeriod();
        if ("24".equals(period)){
            ustomReportModel.setPeriod("D10");
        }
        int res = crCommonOprDao.modifyReportPeriod(ustomReportModel, null);

        return 0 == res;
    }

    @Override
    public List<String> getReportOfDownDependency(String reportKey) {
        //获取指定依赖报表的报表SQL
        String sqlStr= getSql(reportKey);

        //返回查询结果报表的key
        return reportAndSourceStatusDao.getRslt(sqlStr);
    }



   /*
    * @Author: chq
    * @desc: 前端可一次填充多个待查询的依赖报表，使用分号分割
    * @date: 2020/9/8 11:01
    */
    private String getSql(String reportKey) {
        String initSqlStr = "SELECT distinct report_key  FROM report_sql WHERE is_enable = 1 AND (";
        String[] mysqlReportArray = reportKey.split(";");
        for (String mysqlReport : mysqlReportArray) {
            initSqlStr += "(report_dependency RLIKE '.*," + mysqlReport + "$' OR report_dependency RLIKE '^"
                    + mysqlReport + ",.*' OR report_dependency RLIKE '.*," + mysqlReport
                    + ",.*' OR report_dependency='" + mysqlReport + "') OR ";
        }
        String rsltSqlStr = initSqlStr.substring(0, initSqlStr.length() - 4) + ")";
        logger.info("查询上游依赖报表的报表SQL为："+rsltSqlStr);
        return rsltSqlStr;
    }

    /**
     * 发布自定义报表"6"号状态的处理
     *
     * @param crpm
     * @param pubStatus
     * @param statusList
     * @return
     */
    private String crPubSixStatusHandlerFunc(CustomReportModel crpm, String pubStatus, List<String> statusList) {
        String resMsg = "";
        String code = "0";

        int res = crCommonOprDao.writeMysqlStrToDB(crpm, pubStatus);
        if (0 == res) {
            resMsg += "发布自定义报表修改实时SQL配置入库成功,";
        } else {
            resMsg += "发布自定义报表修改实时SQL配置入库失败,";
            code = "3";
        }
        res = crPublishDao.modifyMysqlTmpTbl(crpm);
        if (0 == res) {
            resMsg += "发布自定义报表修改Mysql语句tmp表为正式表成功,";
        } else {
            resMsg += "发布自定义报表修改Mysql语句tmp表为正式表失败,";
            code = "3";
        }
        //更新表数据并删除tmp表
        String resStr = crPublishDao.updateAndDropTmpTable(crpm);
        String[] resArray = resStr.split(Constant.ERR_MSG_SPLIT_FLAG, -1);
        resMsg += resArray[1] + ",";
        if (!"0".equals(resArray[0])) {
            code = resArray[0];
        }

        return code + Constant.CUSTOM_REPORT_STATUS_SPLIT + resMsg;
    }

    /**
     * 发布自定义报表"7"号状态的处理
     *
     * @param crpm
     * @param pubStatus
     * @param statusList
     * @param alreadyDropView
     * @return
     */
    private String crPubSevenStatusHandlerFunc(CustomReportModel crpm, String pubStatus,
                                               List<String> statusList, Boolean alreadyDropView) {
        String resMsg = "";
        String code = "0";

        int result = crCommonOprDao.modifyHistorySqlNote(crpm, pubStatus);
        if (0 == result) {
            resMsg += "发布自定义报表修改历史SQL配置入库成功,";
        } else {
            resMsg += "发布自定义报表修改历史SQL配置入库失败,";
            code = "3";
        }
        String resStr = crPublishDao.dropViewRefFormal(crpm);
        if (resStr.startsWith("0") && "0".equals(code)) {
            logger.info("自定义报表 " + crpm.getId() + " => " + crpm.getApplysqlname() + " 直接执行历史SQL!");
            String delRes = crPublishDao.delFormalTblData(crpm);
            String[] rArray = delRes.split(Constant.ERR_MSG_SPLIT_FLAG, -1);
            resMsg += rArray[1] + ",";
            if (delRes.startsWith("0")) {
                // 执行自定义报表历史SQL
                execReportHistorySql(crpm);
                resMsg += "发布自定义报表开始执行历史SQL,";
            } else {
                code = "3";
            }
        }

        if (!alreadyDropView) {
            String[] resArray = resStr.split(Constant.ERR_MSG_SPLIT_FLAG, -1);
            resMsg += resArray[1] + ",";
            if (!"0".equals(resArray[0])) {
                code = resArray[0];
            }
        }

        return code + Constant.CUSTOM_REPORT_STATUS_SPLIT + resMsg;
    }

    /**
     * 提交报表历史SQL执行请求
     *
     * @param crpm
     */
    private void execReportHistorySql(CustomReportModel crpm) {
        ReportParam rp = new ReportParam();
        rp.setIsCustom("1");
        rp.setHistory("1");
        rp.setKpi(crpm.getApplysqlname());
        rp.setApplyId(crpm.getId());
        if ("0".equals(crpm.getEnable())) {
            rp.setEnable("0");
        }
        execute(rp);
    }

    /**
     * 根据提交的自定义报表信息，拼接SQL组装为Map执行，此处不写入报表配置库
     *
     * @param crm
     * @param pubStatus
     */
    private void execReportManualMapSql(CustomReportModel crm, String pubStatus) {
        Map<String, ReportConfiguration> confMap = crCommonOprDao.createMysqlStr(crm, pubStatus);
        ReportParam rp = new ReportParam();
        rp.setKpi(crm.getApplysqlname());
        rp.setApplyId(crm.getId());
        rp.setIsCustom("1");
        rp.setDataMap(confMap);
        rp.setIsSchedule("1");
        rp.setDataResources(crm.getDataResources());
        if ("0".equals(crm.getEnable())) {
            rp.setEnable("0");
        }
        execute(rp);
    }

    /**
     * 提交报表实时SQL执行请求
     *
     * @param crm
     */
    private void execReportHiveSql(CustomReportModel crm) {
        ReportParam rp = new ReportParam();
        rp.setIsCustom("1");
        rp.setKpi(crm.getApplysqlname());
        rp.setApplyId(crm.getId());
        if ("0".equals(crm.getEnable())) {
            rp.setEnable("0");
        }
        execute(rp);
    }

    /**
     * 创建报表指标结果表
     *
     * @param brtm
     * @return
     */
    public String buildResultTbl(BuildResultTblModel brtm) {

        return customReportDao.createResultMysqlTbl(brtm);
    }

    /**
     * 下线报表
     *
     * @param reportKey
     * @return
     */
    public String offlineReportKey(String reportKey) {

        return crPublishDao.offlineReport(reportKey);
    }

    @Override
    public String updateDataResources(DataResourcesModel dataResourcesModel) {
        return reportMetadataOpr.updateDataResources(dataResourcesModel);
    }

    @Override
    public void rerunDataResourcesReport(DataResourcesModel dataResourcesModel) {
        String metaStatus = dataResourcesModel.getMetaStatus();
        if ("SUCCESS".equals(metaStatus)) {
            String metaKey = dataResourcesModel.getMetaKey();
            ReportParam rp = new ReportParam();
            rp.setDataResources(metaKey);
            rp.setIsSchedule("2");
            execute(rp);
        }
    }

    @Override
    public String updateReportConfig(ReportConfigParam configParam) {
        String resMsg = "";
        try {
            if (null == configParam) {
                resMsg = "修改报表配置参数不能为空";
                return resMsg;
            }

            List<ReportConfigData> paramList = configParam.getParam();
            for (ReportConfigData configData : paramList) {
                String kpi = configData.getKpi();
                if (!ToolUtils.isNotNull(kpi)) {
                    resMsg += "kpi 不能为空";
                    return resMsg;
                }

                List<ReportFieldData> fieldDataList = configData.getChangeValue();

                resMsg = constructSQLByFieldData(kpi, fieldDataList, resMsg);
            }

            if (!ToolUtils.isNotNull(resMsg)) {
                resMsg = "报表配置修改成功";
            }
        } catch (Exception e) {
            resMsg = "报表配置修改失败";
            logger.info("报表配置修改失败: ", e);
        }

        return resMsg;
    }

    /**
     * 构造需要修改的报表配置SQL
     *
     * @param kpi
     * @param fieldDataList
     * @param resMsg
     * @return
     * @author SJ
     */
    private String constructSQLByFieldData(String kpi, List<ReportFieldData> fieldDataList, String resMsg) {
        List<String> sqlList = new ArrayList<>();
        StringBuffer sqlBuffer;
        for (ReportFieldData fieldData : fieldDataList) {
            sqlBuffer = new StringBuffer("update " + CustomConfiguration.getString("report_table") + " set ");
            String reportIndex = fieldData.getReportIndex();
            if (!ToolUtils.isNotNull(reportIndex)) {
                resMsg += "reportKey [ " + kpi + " ] ,reportIndex 不能为空";
                return resMsg;
            }

            List<Map<String, String>> fieldMapList = fieldData.getFields();
            Iterator<Map<String, String>> mapIterator = fieldMapList.iterator();
            while (mapIterator.hasNext()) {
                Map<String, String> map = mapIterator.next();
                String fieldName = map.get("field_name");
                String fieldValue = map.get("field_value");
                if (!ToolUtils.isNotNull(fieldName) || !ToolUtils.isNotNull(fieldValue)) {
                    resMsg += "reportKey [ " + kpi + " ] ,reportIndex [ " + reportIndex + " ] ,fieldName或fieldValue" +
                            "不能为空";
                    return resMsg;
                }
                sqlBuffer.append(fieldName + " = \"" + fieldValue + "\"");
                sqlBuffer.append(",");
            }

            if (null != sqlBuffer && sqlBuffer.length() > 0) {
                sqlBuffer.deleteCharAt(sqlBuffer.length() - 1);
                sqlBuffer.append(" where ");
                sqlBuffer.append(" report_key ");
                sqlBuffer.append(" = ");
                sqlBuffer.append("'" + kpi + "'");
                sqlBuffer.append(" and ");
                sqlBuffer.append(" report_index ");
                sqlBuffer.append(" = ");
                sqlBuffer.append("'" + reportIndex + "'");
                sqlList.add(sqlBuffer.toString());
            }

            logger.info(" *** 构造需要执行的SQL *** " + sqlBuffer.toString());
        }

        Map<String, String> resultMap = crCommonOprDao.updateReportConfig(sqlList);
        if (null != resultMap && resultMap.size() > 0) {
            resMsg += JSONObject.toJSONString(resultMap);
        }

        return resMsg;
    }

    @Override
    public void getDataResourcesAndReportDependency(String reportKey, DependencyModel result) {
        List<DataResourcesStatusModel> dataResourcesStatus =
                reportAndSourceStatusDao.getDependencyDataResourcesStatus(reportKey);
        Set<ReportDependencyStatusModel> upReportDependencyStatus = new HashSet<>();
        Set<ReportDependencyStatusModel> downReportDependencyStatus = new HashSet<>();

        reportAndSourceStatusDao.getUpDependencyReportDependencyStatus(upReportDependencyStatus, reportKey);
        reportAndSourceStatusDao.getDownDependencyReportDependencyStatus(downReportDependencyStatus, reportKey);

        if (dataResourcesStatus == null && upReportDependencyStatus == null && downReportDependencyStatus == null) {
            result.setStatus("-2");
            result.setMsg("获取数据源状态和依赖报表状态均失败");
        } else if (dataResourcesStatus == null) {
            result.setStatus("-3");
            result.setMsg("获取数据源状态失败");
        } else if (upReportDependencyStatus == null && downReportDependencyStatus == null ||
                upReportDependencyStatus == null && downReportDependencyStatus != null ||
                upReportDependencyStatus != null && downReportDependencyStatus == null) {
            result.setStatus("-4");
            result.setMsg("获取依赖报表状态失败");
        } else {
            result.setStatus("0");
            result.setMsg("success");
        }

        result.setData_resources_status(dataResourcesStatus);
        result.setUp_report_dependency_status(upReportDependencyStatus);
        result.setDown_report_dependency_status(downReportDependencyStatus);
    }

    @Override
    public List<String> getResourcesDependencyReport(String reportKey) {
        String searchDependencyReportSql = getSearchDependencyReportSql(reportKey);
        List<String> resourcesDependencyReportList =
                reportAndSourceStatusDao.getResourcesDependencyReportList(searchDependencyReportSql);
        return resourcesDependencyReportList;
    }

    /**
     * @author CHQ
     * @description fix
     */
    @Override
    public void fix() {
        //获取当前正在执行的报表
        ConcurrentHashMap<String, Map<Long, RunStatusModel>> currentReport =
                RunFlagController.getRunReportThreadCache();
        logger.info("当前正在执行的报表信息：" + JSONObject.toJSONString(currentReport));

        //更新配置库和自定义报表库信息，并给前端返回响应结果
        for (String report_key : currentReport.keySet()) {
            String applyId = reportAndSourceStatusDao.getReportApplyId(report_key);
            ResultResponseUtil.resultResponse(Constant.TASK_RES_RETURN_URI, applyId, "3",
                    "发版中，请稍后重试。务必修改SQL之后再提交！！！");

            logger.info("正在更改" + report_key + "自定义报表结果表库信息");
            reportAndSourceStatusDao.changeReportRunStatus(report_key, Constant.REPORT_DEPENDENCY_EXECUTE_FAILED);
            logger.info("更改" + report_key + "自定义报表结果表库信息成功");

            logger.info("正在更改" + report_key + "元数据库信息");
            reportAndSourceStatusDao.updateReportRunTime(report_key, Constant.REPORT_DEPENDENCY_EXECUTE_FAILED,
                    "0", System.currentTimeMillis(), "正在发版中..报表执行失败！");
            logger.info("更改" + report_key + "元数据库信息成功!");
        }
    }

    private String getSearchDependencyReportSql(String reportKey) {
        String dataResourcesSql = "SELECT DISTINCT report_key FROM report_sql WHERE is_enable = 1 AND \n(";
        String[] dataResourcesArray = reportKey.split(";");
        for (String dataResources : dataResourcesArray) {
            dataResourcesSql += "(data_resources RLIKE '.*," + dataResources.trim() + "$' OR data_resources RLIKE '^"
                    + dataResources.trim() + ",.*' OR data_resources RLIKE '.*," + dataResources.trim()
                    + ",.*' OR data_resources='" + dataResources.trim() + "')\nOR ";
        }
        return dataResourcesSql.substring(0, dataResourcesSql.length() - 4) + ")";
    }
}